package org.kwin.spring.transaction;

import org.kwin.ibatis.proxy.AnalyticMethod;
import org.kwin.ibatis.session.SqlSession;
import org.kwin.spring.aop.aspectj.proxy.Proxy;
import org.kwin.spring.aop.aspectj.proxy.ProxyChain;
import org.kwin.spring.beans.factory.BeanFactory;
import org.kwin.spring.jdbc.session.SqlSessionFactory;

import java.lang.reflect.Method;

/**
 * @author : wangkai
 * @version V1.0
 * @Package org.kwin.spring.transaction
 * @Description:
 * @date 2021年10月08日 17:00
 **/
public class TransactionProxy implements Proxy {
    
    private BeanFactory beanFactory;
    
    public TransactionProxy() {
    }
    
    public TransactionProxy(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }
    
    @Override
    public Object doProxy(ProxyChain proxyChain) throws Throwable {
        Object result;
        Method method = proxyChain.getTargetMethod();
        SqlSessionFactory sqlSessionFactory = beanFactory.getBean(SqlSessionFactory.class);
        //加了@Transactional注解的方法要做事务处理
        if (method.isAnnotationPresent(Transactional.class)) {
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
            try {
                // TODO:
                AnalyticMethod.sqlSession.set(sqlSession);
                sqlSession.beginTransaction();
                System.out.println("begin transaction");
                result = proxyChain.doProxyChain();
                sqlSession.commitTransaction();
                System.out.println("commit transaction");
            } catch (Exception e) {
                sqlSession.rollbackTransaction();
                System.out.println("rollback transaction");
                throw e;
            }
        } else {
            SqlSession sqlSession = sqlSessionFactory.openSession();
            AnalyticMethod.sqlSession.set(sqlSession);
            result = proxyChain.doProxyChain();
        }
        return result;
    }
}
